package com.github.catvod.utils;

import org.apache.commons.lang3.StringUtils;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public class AESEncryption {


    public static final String CBC_PKCS_7_PADDING = "AES/CBC/PKCS7Padding";
    public static final String ECB_PKCS_7_PADDING = "AES/ECB/PKCS5Padding";

    public static String encrypt(String word, String keyString, String ivString,String trans) {
        try {
            byte[] keyBytes = keyString.getBytes("UTF-8");
            SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");

            byte[] ivBytes = hexStringToByteArray(ivString);
            IvParameterSpec ivSpec = new IvParameterSpec(ivBytes);

            Cipher cipher = Cipher.getInstance(trans);
            if(StringUtils.isAllBlank(ivString)){
                cipher.init(Cipher.ENCRYPT_MODE, keySpec);

            }else{
                cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);

            }

            byte[] encrypted = cipher.doFinal(word.getBytes("UTF-8"));

            return org.apache.commons.codec.binary.Base64.encodeBase64String(encrypted);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public static String decrypt(String word,String keyString,String ivString,String trans) {
        try {
            // 密钥处理：UTF-8 编码
            byte[] keyBytes = keyString.getBytes("UTF-8");
            SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");

//            // IV 处理：UTF-8 编码
//            byte[] ivBytes = hexStringToByteArray(ivString);
//            IvParameterSpec ivSpec = new IvParameterSpec(ivBytes);

            // 向量偏移处理
            IvParameterSpec ivSpec = null;
            if (trans.contains("CBC")) {
                // 如果是 CBC 模式，需要 IV
                byte[] ivBytes = ivString.getBytes("UTF-8");
                if (ivBytes.length != 16) {
                    throw new IllegalArgumentException("IV length must be 16 bytes.");
                }
                ivSpec = new IvParameterSpec(ivBytes);
            }else {
                byte[] ivBytes = hexStringToByteArray(ivString);
                ivSpec = new IvParameterSpec(ivBytes);
            }

            // 初始化 Cipher
            Cipher cipher = Cipher.getInstance(trans);
            if(StringUtils.isAllBlank(ivString)){
                cipher.init(Cipher.DECRYPT_MODE, keySpec);

            }else{
                cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);

            }
            // Base64 解码密文
            byte[] decoded = org.apache.commons.codec.binary.Base64.decodeBase64(word);
            // 解密
            byte[] decrypted = cipher.doFinal(decoded);

            return new String(decrypted, "UTF-8");
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    // 直接对响应的字节数组进行解密
    public static String decrypt(byte[] word,String keyString,String ivString,String trans) {
        try {
            // 密钥处理：UTF-8 编码
            byte[] keyBytes = keyString.getBytes("UTF-8");
            SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");

//            // IV 处理：UTF-8 编码
//            byte[] ivBytes = hexStringToByteArray(ivString);
//            IvParameterSpec ivSpec = new IvParameterSpec(ivBytes);

            // 向量偏移处理
            IvParameterSpec ivSpec = null;
            if (trans.contains("CBC")) {
                // 如果是 CBC 模式，需要 IV
                byte[] ivBytes = ivString.getBytes("UTF-8");
                if (ivBytes.length != 16) {
                    throw new IllegalArgumentException("IV length must be 16 bytes.");
                }
                ivSpec = new IvParameterSpec(ivBytes);
            }else {
                byte[] ivBytes = hexStringToByteArray(ivString);
                ivSpec = new IvParameterSpec(ivBytes);
            }

            // 初始化 Cipher
            Cipher cipher = Cipher.getInstance(trans);
            if(StringUtils.isAllBlank(ivString)){
                cipher.init(Cipher.DECRYPT_MODE, keySpec);

            }else{
                cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);

            }
            // 解密
            byte[] decrypted = cipher.doFinal(word);
            return new String(decrypted, "UTF-8");
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public static String aesCbcDecrypt(String data, String key) throws Exception {
        byte[] keyBytes = key.substring(0, 16).getBytes("UTF-8");
        byte[] ivBytes = key.substring(16, 32).getBytes("UTF-8");

        SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");
        IvParameterSpec ivSpec = new IvParameterSpec(ivBytes);

        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);

        byte[] hexBytes = hexStringToByteArray(data);
        byte[] decryptedBytes = cipher.doFinal(hexBytes);

        return new String(decryptedBytes, "UTF-8");
    }


    public static byte[] cg51decrypt(String word, String keyString, String ivString, String trans) {
        try {
            byte[] keyBytes = keyString.getBytes("UTF-8");
            SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");

            byte[] ivBytes = ivString.getBytes("UTF-8");
            IvParameterSpec ivSpec = new IvParameterSpec(ivBytes);

            Cipher cipher = Cipher.getInstance(trans);
            if(StringUtils.isAllBlank(ivString)){
                cipher.init(Cipher.DECRYPT_MODE, keySpec);

            }else{
                cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);

            }
            byte[] decoded = org.apache.commons.codec.binary.Base64.decodeBase64(word);
            return cipher.doFinal(decoded);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }



    private static byte[] hexStringToByteArray(String hexString) {
        int len = hexString.length();
        byte[] data = new byte[len / 2];

        for (int i = 0; i < len; i += 2) {
            data[i / 2] = (byte) ((Character.digit(hexString.charAt(i), 16) << 4) + Character.digit(hexString.charAt(i + 1), 16));
        }

        return data;
    }

    public static String encodeURIComponent(String value) {
        try {
            return URLEncoder.encode(value, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException("Error encoding URL component", e);
        }
    }
}